package com.aaa.vegetablemarketexpress.service.impl;

import com.aaa.vegetablemarketexpress.dao.UserDao;
import com.aaa.vegetablemarketexpress.dao.UserRoleDao;
import com.aaa.vegetablemarketexpress.entity.User;
import com.aaa.vegetablemarketexpress.service.RoleService;
import com.aaa.vegetablemarketexpress.service.UserService;
import com.aaa.vegetablemarketexpress.util.*;
import com.aaa.vegetablemarketexpress.vo.UserStatisticsVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Sha512Hash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @FileName: UserServiceImpl
 * @Description:
 * @Author: qxh
 * @CreateTime: 2025/9/6 14:48
 * @Version: 1.0.0
 */
@Service
@Log4j2
public class UserServiceImpl implements UserService {
    @Resource
    private UserDao userDao;// 注入
    @Resource
    private HttpSession session;
    @Resource
    private UserRoleDao userRoleDao;
    @Resource
    private RoleService roleService; // 注入RoleService，查询角色
    /**
     * @Description: 登录校验
     * @Param: [userName, password]
     * @return: com.aaa.vegetablemarketexpress.entity.User
     * @Author: qxh
     * @CreateTime: 2025/9/6 14:48
     */
//    @Override
//    public Result login(String userName, String password) {
//        // 根据用户名查询用户信息
//        User user = new User();
//        user.setUserName(userName);
//        user.setStatus("0");
//        user.setDelFlag("0");
//        //根据用户名查询用户信息
//        List<User> userList = userDao.selectUserList(user);
//        //判判断不为null，继续
//        if(!CollectionUtils.isEmpty( userList)){
//            //获取用户信息
//            User userInfo = userList.get(0);
//            //获取盐值
//            String salt = userInfo.getSalt();
//            //对密码进行加密
//            String newPassword = new Sha512Hash(password, salt, 1024).toString();
//            //判断密码是否一致
//            if(newPassword.equals(userInfo.getPassword())){
//                session.setAttribute("userInfo",userInfo);
//                return ResultUtil.success("登录成功");
//            }
//        }
//        return ResultUtil.failed("登录失败");
//    }

    /**
     *  登录校验
     * @param userName
     * @param password
     * @return
     */
    @Override
    public Result login(String userName, String password) {
        // 根据用户名查询用户信息
        User user = new User();
        user.setUserName(userName);
        user.setStatus("0");
        user.setDelFlag("0");
        //根据用户名查询用户信息
        List<User> userList = userDao.selectUserList(user);
        //判断不为null，继续
        if(!CollectionUtils.isEmpty( userList)){
            //获取用户信息
            User userInfo = userList.get(0);
            //获取盐值
            String salt = userInfo.getSalt();
            //对密码进行加密
            String newPassword = new Sha512Hash(password, salt, 1024).toString();
            //判断密码是否一致
            if(newPassword.equals(userInfo.getPassword())){
                session.setAttribute("userInfo", userInfo);
                // 修复：返回用户信息，而不仅仅是消息
                return ResultUtil.success(userInfo);
            }
        }
        return ResultUtil.failed("登录失败");
    }
    /**
     * shiro登录
     * @param userName
     * @param password
     * @return
     */
    @Override
    public Result checkUser(String userName, String password) {
        //收集用户信息(用户名，密码)
        AuthenticationToken usernamePasswordToken = new UsernamePasswordToken(userName, password);
        //获取主体对象
        Subject currentUser = SecurityUtils.getSubject();
        try {
            //登录
            currentUser.login(usernamePasswordToken);
            //获取session
            Session session = currentUser.getSession();
            //获取用户信息
            User user = (User) currentUser.getPrincipal();
            //添加用户信息到session
            session.setAttribute("userInfo", user);
                    return ResultUtil.success(user);

        }
        catch (AuthenticationException e) {
            e.printStackTrace();

        } return ResultUtil.failed("用户名或者密码错误");

    }

    /**
     * @Description: 根据id查询用户信息
     * @Param: [userId]
     * @return: com.aaa.vegetablemarketexpress.entity.User
     * @Author: qxh
     * @CreateTime: 2025/9/6 14:48
     */
    @Override
    public User selectUserById(Long userId) {
        return userDao.selectUserById(userId);
    }
    /**
     * @Description: 查询用户列表
     * @Param: [page]
     * @return: com.github.pagehelper.PageInfo<com.aaa.vegetablemarketexpress.entity.User>
     * @Author: qxh
     * @CreateTime: 2025/9/6 14:48
     */
    @Override
    public PageInfo selectUserList(Page<User> page) {
        if(page.getPageNo() == null || page.getPageNo() == 0|| page.getPageSize() == null || page.getPageSize() == 0){
            throw new CustomException(ResultStatus.PARAM_ISNULL.getStatusCode(), ResultStatus.PARAM_ISNULL.getStatusMsg());
        }
        PageHelper.startPage(page.getPageNo(),page.getPageSize());
        User data = page.getData();
        return new PageInfo<>(userDao.selectUserList(data));
    }
    /**
     * @Description: 添加用户,为用户添加密码，生成盐值，对密码进行加密
     * @Param: [user]
     * @return: User
     * @Author: qxh
     * @CreateTime: 2025/9/6 14:48
     */
    @Override
    public User insertUser(User user) {
        String s = checkUserNameUnique(user);
        if ("0".equals(s)){
            //获取原始密码
            String oldPassword = user.getPassword();
            //生成盐值
            String salt = UUID.randomUUID().toString();
            //对密码进行加密
            String newPassword = new Sha512Hash(oldPassword, salt, 1024).toString();
            //设置盐值
            user.setSalt(salt);
            //设置密码
            user.setPassword(newPassword);
            //设置创建时间
            user.setCreateTime(new Date());
            //设置账号状态
            user.setStatus("0");
            //设置删除标志
            user.setDelFlag("0");
            this.userDao.insertUser(user);//添加用户
            return user;//返回用户信息
        }else {
            throw new CustomException(ResultStatus.DATA_USERNAME_EXIST.getStatusCode(),  ResultStatus.DATA_USERNAME_EXIST.getStatusMsg());
        }



    }
    /**
     * @Description: 修改用户
     * @Param: [user]
     * @return: int
     * @Author: qxh
     * @CreateTime: 2025/9/6 14:48
     */
    @Override
    public int updateUser(User user) {
        // 验证用户ID是否存在
        if (user.getUserId() == null) {
            throw new CustomException(ResultStatus.PARAM_ISNULL.getStatusCode(), "用户ID不能为空");
        }
        // 验证用户是否存在
        User existingUser = userDao.selectUserById(user.getUserId());
        if (existingUser == null) {
            throw new CustomException(ResultStatus.PARAM_ISNULL.getStatusCode(), "用户不存在");
        }
        // 如果修改了密码，需要重新加密
        if (user.getPassword() != null && !user.getPassword().isEmpty()
                && !user.getPassword().equals(existingUser.getPassword())) {// 修改了密码
            String salt = UUID.randomUUID().toString();
            String newPassword = new Sha512Hash(user.getPassword(), salt, 1024).toString();
            user.setPassword(newPassword);
            user.setSalt(salt);
        } else {
            // 如果没修改密码，保持原密码
            user.setPassword(existingUser.getPassword());
            user.setSalt(existingUser.getSalt());
        }
        //user.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        user.setUpdateTime(new Date());
        // 确保创建时间不被修改
        user.setCreateTime(existingUser.getCreateTime());
        user.setCreateBy(existingUser.getCreateBy());
        return this.userDao.updateUser(user);
    }
    /**
     * @Description: 删除用户
     * @Param: [userId]
     * @return: int
     * @Author: qxh
     * @CreateTime: 2025/9/6 14:48
     */
    @Override
    public int deleteUserById(Long userId) {
        return this.userDao.deleteUserById(userId);
    }
    /**
     * @Description: 验证用户名唯一
     * @Param: [user]
     * @return: java.lang.String
     * @Author: qxh
     * @CreateTime: 2025/9/6 14:48
     */
    @Override
    public String checkUserNameUnique(User user) {
        int count = userDao.checkUserNameUnique(user.getUserName());
        log.info("用户名[{}]唯一性校验，存在{}条记录", user.getUserName(), count); // 新增日志
        if (count > 0) {
            return "1"; // 已存在
        }
        return "0"; // 不存在
    }
    /**
     * @Description: 根据用户ID查询用户信息，并返回用户信息及角色信息
     * @Param: [userId]
     * @return: com.aaa.vegetablemarketexpress.entity.User
     * @Author: qxh
     * @CreateTime: 2025/9/6 14:48
     */
    @Override
    public User selectUserByIdWithRoles(Long userId) {
        User user = userDao.selectUserById(userId);
        if (user != null) {
            // 查询用户拥有的角色ID列表
            List<Long> roleIds = userRoleDao.selectRoleIdsByUserId(userId);
            if (roleIds != null && !roleIds.isEmpty()) {
                user.setRoleIds(roleIds);
            }
        }
        return user;
    }
    /**
     * @Description: 为用户添加角色
     * @Param: [userId, roleIds]
     * @return: int
     * @Author: qxh
     * @CreateTime: 2025/9/6 14:48
     */
    @Override
    @Transactional
    public int insertUserAuth(Long userId, Long[] roleIds) {
        // 先删除用户的所有角色
        userRoleDao.deleteUserRoleByUserId(userId);

        // 再插入新的角色
        if (roleIds != null && roleIds.length > 0) {
            return userRoleDao.batchUserRole(userId, roleIds);
        }
        return 1;
    }
    /**
     * @Description: 验证用户身份（忘记密码功能）
     * @Param: [userName, phone, captcha]
     * @return: com.aaa.vegetablemarketexpress.util.Result
     * @Author: qxh
     * @CreateTime: 2025/9/6 14:48
     */
    @Override
    public Result verifyUser(String userName, String phone, String captcha) {
        // 根据用户名和手机号查询用户
        User user = userDao.selectUserByUserNameAndPhone(userName, phone);
        if (user == null) {
            return ResultUtil.failed("用户不存在");
        }

        // 验证验证码是否过期（5分钟内有效）
        if (user.getUpdateTime() == null) {
            return ResultUtil.failed("验证码已过期");
        }

        long currentTime = System.currentTimeMillis();
        long updateTime = user.getUpdateTime().getTime();
        long timeDiff = currentTime - updateTime;

        // 5分钟=300000毫秒
        if (timeDiff > 300000) {
            return ResultUtil.failed("验证码已过期，请重新获取");
        }

        // 验证验证码（与remark字段匹配）
        if (user.getRemark() == null || !user.getRemark().equals(captcha)) {
            return ResultUtil.failed("验证码错误");
        }

        // 验证成功后清除database中的验证码
        user.setRemark(null);
        user.setUpdateTime(new Date());
        userDao.updateUser(user);

        return ResultUtil.success(user);
    }

    /**
     * @Description: 重置用户密码
     * @Param: [userId, newPassword]
     * @return: int
     * @Author: qxh
     * @CreateTime: 2025/9/6 14:48
     */
    @Override
    public int resetPassword(Long userId, String newPassword) {
        // 验证用户是否存在
        User existingUser = userDao.selectUserById(userId);
        if (existingUser == null) {
            throw new CustomException(ResultStatus.PARAM_ISNULL.getStatusCode(), "用户不存在");
        }

        // 生成盐值
        String salt = UUID.randomUUID().toString();
        // 对新密码进行加密
        String encryptedPassword = new Sha512Hash(newPassword, salt, 1024).toString();

        // 创建更新用户对象
        User user = new User();
        user.setUserId(userId);
        user.setPassword(encryptedPassword);
        user.setSalt(salt);
        user.setUpdateTime(new Date());

        // 更新用户密码
        return this.userDao.updateUser(user);
    }

    /**
     * 隐藏邮箱信息
     * @param email 邮箱
     * @return 隐藏后的邮箱
     */
    private String hideEmail(String email) {
        if (email == null || email.isEmpty()) {
            return "";
        }
        int atIndex = email.indexOf("@");
        if (atIndex <= 1) {
            return email;
        }
        return email.substring(0, 2) + "***" + email.substring(atIndex - 1);
    }

    /**
     * 隐藏手机号信息
     * @param phoneNumber 手机号
     * @return 隐藏后的手机号
     */
    private String hidePhoneNumber(String phoneNumber) {
        if (phoneNumber == null || phoneNumber.length() < 7) {
            return phoneNumber;
        }
        return phoneNumber.substring(0, 3) + "****" + phoneNumber.substring(7);
    }
    /**
     * 判断用户是否为管理员
     * @param userId 用户ID
     * @return true表示是管理员，false表示不是管理员
     */
    @Override
    public boolean isAdmin(Long userId) {
        if (userId == null) {
            return false;
        }
        try {
            long count = userDao.checkIsAdmin(userId);
            return count > 0;
        } catch (Exception e) {
            log.error("检查用户是否为管理员时发生异常，用户ID: {}", userId, e);
            return false;
        }
    }
    @Override
    public boolean isMerchant(Long userId) {
        if (userId == null) {
            return false;
        }
        try {
            // 查询用户的角色列表
            User user = userDao.selectUserById(userId);
            if (user == null) {
                return false;
            }
            List<Long> roleIds = userRoleDao.selectRoleIdsByUserId(userId);
            if (CollectionUtils.isEmpty(roleIds)) {
                return false;
            }
            // 检查是否有“商家”角色
            for (Long roleId : roleIds) {
                String roleName = roleService.queryByRoleId(roleId).getRoleName();
                if ("商家".equals(roleName)) {
                    return true;
                }
            }
            return false;
        } catch (Exception e) {
            log.error("判断用户是否为商家时发生异常，用户ID: {}", userId, e);
            return false;
        }
    }
    /**
     * 获取用户统计信息
     * @param params 查询参数
     * @return 用户统计信息
     */
    @Override
    public UserStatisticsVO getUserStatistics(Map<String, Object> params) {
        UserStatisticsVO statistics = userDao.selectUserStatistics(params);

        // 获取各图表数据
        List<Map<String, Object>> genderData = userDao.selectUserGenderDistribution(params);
        List<Map<String, Object>> statusData = userDao.selectUserStatusDistribution(params);
        List<Map<String, Object>> trendData = userDao.selectUserRegisterTrend(params);
        List<Map<String, Object>> deptData = userDao.selectUserDeptDistribution(params);

        statistics.setGenderData(genderData);
        statistics.setStatusData(statusData);
        statistics.setTrendData(trendData);
        statistics.setDeptData(deptData);

        return statistics;
    }

    @Override
    public Result updatePassword(User user,String newPassword) {
        User userInfo = (User) session.getAttribute("userInfo");
        if (userInfo == null){
            return ResultUtil.failed("用户未登录");
        }
        Long userId = userInfo.getUserId();
        // 获取前端传来的 旧密码
        String oldPassword = user.getPassword();
        if (StringUtils.isEmpty(oldPassword)||StringUtils.isEmpty(newPassword)){
            return ResultUtil.failed("旧密码和新密码不能为空");
        }
        // 获取登录用户的盐值
        String salt = userInfo.getSalt();
        // 获取登录用户的加密之后的密码
        String password = userInfo.getPassword();
        // 对前端传来的旧密码进行加密
        String encryptedPassword = new Sha512Hash(oldPassword, salt, 1024).toString();
        //判断旧密码加密之后的密码 与 登录用户的加密密码 是否一致
        if(!encryptedPassword.equals(password)){
            return ResultUtil.failed("旧密码错误");
        }
        //生成盐值
        String newSalt = UUID.randomUUID().toString();
        //对新密码进行加密
        String encryptedNewPassword = new Sha512Hash(newPassword, newSalt, 1024).toString();
        // 创建更新用的用户对象
        User updateUser  = new User();
        updateUser.setUserId(userId);
        updateUser.setPassword(encryptedNewPassword);
        updateUser.setSalt(newSalt);
        // 设置更新者信息，通常是当前登录用户
        updateUser.setUpdateBy(userInfo.getUserName());
        updateUser.setUpdateTime(new Date());
        int i = userDao.updateUser(updateUser);
        if (i > 0){
            // 更新会话中的用户信息
            userInfo.setPassword(encryptedNewPassword);
            userInfo.setSalt(newSalt);
            userInfo.setUpdateTime(new Date());
            userInfo.setUpdateBy(userInfo.getUserName());
            session.setAttribute("userInfo", userInfo);
            return ResultUtil.success("密码修改成功");
        }else {
            return ResultUtil.failed("密码修改失败");
        }
    }

    @Override
    public int forgetPassword(User user) {
        String userName = user.getUserName();
        String phonenumber = user.getPhonenumber();
        User existingUser = new User();
        existingUser.setUserName(userName);
        existingUser.setPhonenumber(phonenumber);
        // 验证用户是否存在
        List<User> userList = userDao.selectUserList(existingUser);
        if (CollectionUtils.isEmpty(userList)) {
            throw new CustomException(ResultStatus.PARAM_ISNULL.getStatusCode(), "用户不存在");
        }
        User user1 = userList.get(0);
        if (user1==null){
            throw new CustomException(ResultStatus.PARAM_ISNULL.getStatusCode(), "用户不存在");
        }
        // 修改密码
            String salt = UUID.randomUUID().toString();
            String newPassword = new Sha512Hash(user.getPassword(), salt, 1024).toString();
            user.setPassword(newPassword);
            user.setSalt(salt);

        //user.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        user.setUpdateTime(new Date());
        // 确保创建时间不被修改
        user.setCreateTime(user1.getCreateTime());
        user.setCreateBy(user1.getCreateBy());
        user.setUserId(user1.getUserId());
        System.out.println("++++++++++++++++"+user);
        return this.userDao.updateUser(user);
    }
    /**
     * 根据用户名查询用户信息
     * @param userName 用户名
     * @return 用户信息
     */
    @Override
    public User queryByUsername(String userName) {
        //实例化用户参数对象
        User user = new User();
        user.setUserName(userName);
        user.setStatus("0");
        user.setDelFlag("0");
        //查询用户
        List<User> userList = userDao.selectUserList(user);
        //判断用户是否存在
        if(!CollectionUtils.isEmpty(userList)){
            return userList.get(0);//返回用户
        }
        return null;
    }
    
    /**
     * 根据用户名和手机号查询用户
     * @param userName 用户名
     * @param phone 手机号
     * @return 用户信息
     */
    @Override
    public User selectUserByUserNameAndPhone(String userName, String phone) {
        return userDao.selectUserByUserNameAndPhone(userName, phone);
    }
//
//    /**
//     * shiro登录
//     * @param userName
//     * @param password
//     * @return
//     */
//    @Override
//    public Result login(String userName, String password) {
//        //收集用户信息（用户名和密码）
//        UsernamePasswordToken usernamePasswordToken =
//                new UsernamePasswordToken(userName, password);
//        //获取Subject
//        //Subject currentUser = SecurityUtils.getSubject();
//        Subject subject = SecurityUtils.getSubject();
//        try {
//            //登录
//            subject.login(usernamePasswordToken);
//            //获取登录用户信息
//            User user = (User) subject.getPrincipal();
//            //把当前登录用户放入session
//            session.setAttribute("userInfo", user);
//            BaseUtil.
//        } catch (UnknownAccountException e) {
//            return ResultUtil.failed("用户不存在");
//        } catch (IncorrectCredentialsException e) {
//            return ResultUtil.failed("密码错误");
//        } catch (LockedAccountException e) {
//            return ResultUtil.failed("用户被锁定");
//        } catch (AuthenticationException e) {}
//
//    }
}

